/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.brain.come.manager;

import com.brain.come.dto.DocumentoVentaDto;
import com.brain.come.dto.PlanCobroDto;
import com.brain.come.view.util.ConstantesCome;
import com.brain.conf.dto.TipoCambioDto;
import com.brain.conf.manager.TipoCambioManager;
import com.brain.core.common.ExportarExcelCaja;
import com.brain.core.manager.*;
import com.brain.core.common.UtilCore;
import com.brain.core.configuracion.WebServletContextListener;
import com.brain.core.dto.FechaFiltroDto;
import com.brain.core.exception.DAOException;
import com.brain.core.hibernate.dao.DAOGenerico;
import com.brain.core.view.mbean.ApplicationMBean;
import com.brain.core.view.mbean.SessionMBean;
import com.brain.core.view.util.ConstantesCore;
import com.brain.fina.dto.CobroDto;
import com.brain.fina.manager.CobroManager;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import javax.annotation.Resource;
import javax.faces.model.SelectItem;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

/**
 *
 * @author Indra
 */
@Service
public class PlanCobroManager extends ComunManager<PlanCobroDto> implements Serializable {

    private static Logger logger = Logger.getLogger(PlanCobroManager.class);
    private Long idEntidad = 183L;
    @Resource
    private DAOGenerico<PlanCobroDto> springHibernateDao;
    @Resource
    private RecursosManager recursosManager;
    @Resource
    private CobroManager managerCobro;
    
    private final String url = "/pages/caja/cobroDV/planCobroDV.xhtml";
    private final String urlLista = "/pages/caja/cobroDV/listaPlanCobroDV.xhtml";

    /**
     * obtener Plan de Cobro por Id
     *
     * @param id ID de Plan de Cobro
     * @return Plan de Cobro
     * @throws DAOException
     */
    public PlanCobroDto obtenerPorId(Long id) throws DAOException {
        return springHibernateDao.obtenerDtoPorId(PlanCobroDto.class, id);
    }

    /**
     * Metodo para inicializar un nuevo Plan de Cobro
     *
     * @return
     */
    
    public List<PlanCobroDto> obtenerDocumentosVentaXPagar(PlanCobroDto dto, FechaFiltroDto dtoFecha) throws DAOException{
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        List<Object> listaParametros = new ArrayList<Object>();
        
        String query = "select dto from PlanCobroDto as dto where dto.documentoVentaDto.organizacionDto.id = ?";        
        listaParametros.add(sessionMBean.getOrganizacionDto().getId());
        
        if (dto.getId() != null  && !dto.getId().equals(0L)){
            query += " and dto.id = ?";
            listaParametros.add(dto.getId());
        }
        else{
            
            if (dto.getEstado()!=null && !dto.getEstado().equals(ConstantesCome.ValoresConstantes.PLAN_COBRO_COD_ESTADO_TODOS)) {
                query+=" and dto.estado = ?";
                listaParametros.add(dto.getEstado());
            }
            
            if (dtoFecha.getFechaInicio() != null && dtoFecha.getFechaFin() != null){
                if(listaParametros.size()>0){
                    query+=" and dto.fechaVencimiento between ? and ?";
                }else{
                    query+=" where dto.fechaVencimiento between ? and ?";
                }
                Calendar c = Calendar.getInstance();
                c.setTime(dtoFecha.getFechaInicio());
                c.set(Calendar.HOUR, 0);
                c.set(Calendar.MINUTE,0);
                c.set(Calendar.SECOND,0);
                listaParametros.add(c.getTime());
                c.setTime(dtoFecha.getFechaFin());
                c.set(Calendar.HOUR, 23);
                c.set(Calendar.MINUTE,59);
                c.set(Calendar.SECOND,59);
                listaParametros.add(c.getTime());
            }                        
        }
        query += " order by dto.fechaVencimiento desc";
        
        return springHibernateDao.ejecutarQuery(query, listaParametros);
    }
    
    public PlanCobroDto inicializar() {
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        PlanCobroDto dto = new PlanCobroDto();
        dto.setLiquidar(BigDecimal.ZERO);
        dto.setCobrado(BigDecimal.ZERO);
        dto.setPendiente(BigDecimal.ZERO);
        dto.setUltimoCobroDto(null);
        dto.setNumeroCobro(1);
        dto.setIsSave(Boolean.TRUE);
        dto.setEstado(ConstantesCome.ValoresConstantes.PLAN_COBRO_COD_ESTADO_PENDIENTE);
        dto.setUsuarioCancelacionDto(null);
        return dto;
    }

    /**
     * Metodo para guardar, editar Plan de Cobro
     *
     * @param dto Plan de Cobro
     * @return cadena de satisfaccion
     */
    public String guardar(PlanCobroDto dto) {
        String to = null;
        String mensajeTrx = "";
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        ApplicationMBean applicationMBean = (ApplicationMBean) WebServletContextListener.getApplicationContext().getBean("applicationMBean");

        try {
            if (dto.getIsSave()) {
                {
                    dto.setUsuarioDto(sessionMBean.getSessionUsuarioDto());
                    dto.setFecha(UtilCore.Fecha.obtenerFechaActualDate());
                    dto.setTerminal(sessionMBean.getSessionTerminal());
                }

                if (sessionMBean.getAccionDetalle() == applicationMBean.getNuevo()) {
                    dto.setUsuarioCreacionDto(sessionMBean.getSessionUsuarioDto());
                    dto.setFechaCreacion(UtilCore.Fecha.obtenerFechaActualDate());
                    dto.setTerminalCreacion(sessionMBean.getSessionTerminal());
                    UtilCore.General.toUpperCaseDto(dto);
                    dto.setPendiente(dto.getLiquidar());
                    definirCssPorEstado(dto);
                    nuevo(dto);
                    mensajeTrx = UtilCore.Internacionalizacion.getMensajeInternacional("form.general.mensaje.transaccion.ok");
                    recursosManager.showMessage(mensajeTrx);
                    to = "";//retroceder();
                } else if (sessionMBean.getAccionDetalle() == applicationMBean.getEditar()) {
                    UtilCore.General.toUpperCaseDto(dto);                
                    editar(dto);
                    mensajeTrx = UtilCore.Internacionalizacion.getMensajeInternacional("form.general.mensaje.transaccion.ok");
                    recursosManager.showMessage(mensajeTrx);
                    to = "";//retroceder();
                }
            }else{
               recursosManager.showError(UtilCore.Internacionalizacion.getMensajeInternacional("plan.cobro.mensaje.issave.false")); 
            }
        } catch (Exception ex) {   
            mensajeTrx = ex.getMessage();
            recursosManager.showError(ex.getMessage());
            logger.error(mensajeTrx);
            
            to = null;
        }
        return to;
    }
    
    public String cobrar(PlanCobroDto dto){
        String to = null;
        String mensajeTrx = "";
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        ApplicationMBean applicationMBean = (ApplicationMBean) WebServletContextListener.getApplicationContext().getBean("applicationMBean");
                
        for(CobroDto x: dto.getListaCobro()){
            if (x.getEstado().equals("P")){
                x.setEstado("C");
                x.setUsuarioCancelacionDto(sessionMBean.getSessionUsuarioDto());
                x.setFechaCancelacion(UtilCore.Fecha.obtenerFechaActualDate());
            }
        }

        dto.setCobrado(dto.getLiquidar());
        dto.setPendiente(BigDecimal.ZERO);
        
        try {
            dto.setEstado(ConstantesCome.ValoresConstantes.PLAN_COBRO_COD_ESTADO_CANCELADO);
            dto.setUsuarioCancelacionDto(sessionMBean.getSessionUsuarioDto());
            dto.setFechaCancelacion(UtilCore.Fecha.obtenerFechaActualDate());
            definirCssPorEstado(dto);
            UtilCore.General.toUpperCaseDto(dto);
            editar(dto);
            mensajeTrx = UtilCore.Internacionalizacion.getMensajeInternacional("form.general.mensaje.transaccion.ok");
            recursosManager.showMessage(mensajeTrx);
            to = "";
        } catch (DAOException ex) {
            mensajeTrx = ex.getMessage();
            recursosManager.showError(ex.getMessage());
            logger.error(mensajeTrx);
            to = null;
        }
        return to;
    }
    
    public String cobrarCobro(PlanCobroDto dto){
        String to = null;
        String mensajeTrx = "";
        if (dto.getPendiente().compareTo(BigDecimal.ZERO) == 0){   
            this.cobrar(dto);
            to = null;
        }
        else{
            try {
                UtilCore.General.toUpperCaseDto(dto);
                editar(dto);
                to = "";
             } catch (DAOException e) {
                mensajeTrx = e.getMessage();
                logger.error(mensajeTrx);
                to = null;
             }
        }
        return to;
    }

    public BigDecimal obtenerSumaMontosALiquidar(DocumentoVentaDto dto,PlanCobroDto planCobroDto) throws DAOException {
        List<Object> listaParametros = new ArrayList<Object>();
        String hqsql = "select sum(e.liquidar) from PlanCobroDto as e ";
        hqsql += " where e.documentoVentaDto.id = ?";
        listaParametros.add(dto.getId());
        if (planCobroDto.getId() != null) {
            hqsql += " and e.id <> ?";            
            listaParametros.add(planCobroDto.getId());
        }
        return (BigDecimal) (springHibernateDao.ejecutarQueryGeneric(hqsql, listaParametros).get(0));
    }
    
    public SelectItem[] siTiposPlanCobroTodos(){
        SelectItem[] si = new SelectItem[3];
        si[0] = new SelectItem(ConstantesCome.ValoresConstantes.PLAN_COBRO_COD_ESTADO_TODOS, ConstantesCome.ValoresConstantes.PLAN_COBRO_DESC_ESTADO_TODOS);        
        si[1] = new SelectItem(ConstantesCome.ValoresConstantes.PLAN_COBRO_COD_ESTADO_PENDIENTE, ConstantesCome.ValoresConstantes.PLAN_COBRO_DESC_ESTADO_PENDIENTE);
        si[2] = new SelectItem(ConstantesCome.ValoresConstantes.PLAN_COBRO_COD_ESTADO_CANCELADO, ConstantesCome.ValoresConstantes.PLAN_COBRO_DESC_ESTADO_CANCELADO);        
        return si;
    }
    
    public void definirCssPorEstado(PlanCobroDto dto) {
        if (dto.getEstado().equals(ConstantesCome.ValoresConstantes.PLAN_COBRO_COD_ESTADO_CANCELADO)) {
            dto.setInlinestyle(ConstantesCore.cssEstados.cssConfirmado);
        } else if (dto.getEstado().equals(ConstantesCome.ValoresConstantes.PLAN_COBRO_COD_ESTADO_PENDIENTE)) {
            dto.setInlinestyle(ConstantesCore.cssEstados.cssAnulado);      
        }
    }
    
    public CobroDto unificarDatosCobroDetalle(CobroDto cDto, PlanCobroDto pcDto){
        try {
            cDto = obtenerTipoCambio(cDto, pcDto);
        } catch (Exception e) {
            recursosManager.showError(e.getMessage());
            logger.error(e.getMessage());
        }
        return cDto;
    }
    
    public CobroDto obtenerTipoCambio(CobroDto cDto, PlanCobroDto pcDto){
        TipoCambioDto tcDto = verificarMonedas(cDto, pcDto);
        if (tcDto == null){
            cDto.setFactorConversion(null);
        }
        else if (tcDto.getId().equals(-1L)){
            cDto.setFactorConversion(BigDecimal.ONE);
        }
        else {
            cDto.setFactorConversion(tcDto.getFactor());
        }
        return cDto;        
    }
    
    public TipoCambioDto verificarMonedas(CobroDto cDto, PlanCobroDto dto) {
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        TipoCambioManager tipoCambioManager = (TipoCambioManager) WebServletContextListener.getApplicationContext().getBean("tipoCambioManager");
        TipoCambioDto tcDto = null;
        //Verificamos si es necesario usar el tipo de cambio
        if (!cDto.getMonedaDto().getId().equals(dto.getMonedaDto().getId())) {
            tcDto = tipoCambioManager.obtenerFactorConversionProceso(cDto.getMonedaDto(), dto.getMonedaDto(), sessionMBean.getOrganizacionDto().getTcCompra(), 1);

            if (tcDto.getId() == null) {
                return null;
            }
        } else {
            tcDto = new TipoCambioDto(-1L);
        }
        return tcDto;
    }
    
    public void generarExcelSeleccionados(ExportarExcelCaja.PlanCobro exp, PlanCobroDto[] selectedPCs) {
        StringBuilder strCabecera = this.obtenerCabeceraExcel(exp);
        List<PlanCobroDto> lst = Arrays.asList(selectedPCs);
        List lstCuerpo = this.obtenerCuerpoExcel(exp, lst);
        String nombreArchivo = "PLANES_COBRO_" + UtilCore.Fecha.obtenerFechaHoraActual().replace(':', '_') + ".xls";
        this.recursosManager.generarExcel(strCabecera.toString(), lstCuerpo, nombreArchivo);
        this.recursosManager.viewArchivo(nombreArchivo);
    }
    
    public void generarExcelPorTabla(ExportarExcelCaja.PlanCobro exp, List<PlanCobroDto> lstPC) {
        StringBuilder strCabecera = this.obtenerCabeceraExcel(exp);
        List lstCuerpo = this.obtenerCuerpoExcel(exp, lstPC);
        String nombreArchivo = "PLANES_COBRO_" + UtilCore.Fecha.obtenerFechaHoraActual().replace(':', '_') + ".xls";
        this.recursosManager.generarExcel(strCabecera.toString(), lstCuerpo, nombreArchivo);
        this.recursosManager.viewArchivo(nombreArchivo);
    }
    
    private List obtenerCuerpoExcel(ExportarExcelCaja.PlanCobro exp, List<PlanCobroDto> lst) {
        StringBuilder strCuerpo;
        List lstFilas = new ArrayList();
        for (PlanCobroDto x : lst) {
            strCuerpo = new StringBuilder();
            if (exp.getId()) {
                strCuerpo.append(x.getId()).append("|");
            }
            if (exp.getFechaVencimiento()){
                if (x.getFechaVencimiento() != null){
                    strCuerpo.append(x.getFechaVencimiento()).append("|");
                }
                else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getFormaPago()){
                if (x.getFormaPagoDto() != null){
                    strCuerpo.append(x.getFormaPagoDto().getDescripcion()).append("|");
                }
                else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getLiquidar()){
                if (x.getLiquidar() != null){
                    strCuerpo.append(x.getLiquidar()).append("|");
                }
                else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getCobrado()){
                if (x.getCobrado() != null){
                    strCuerpo.append(x.getCobrado()).append("|");
                }
                else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getPendiente()){
                if (x.getPendiente() != null){
                    strCuerpo.append(x.getPendiente()).append("|");
                }
                else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getUltimoCobro()){
                if (x.getUltimoCobroDto() != null){
                    strCuerpo.append(x.getId()).append("|");
                }
                else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getNumeroCobro()){
                strCuerpo.append(x.getNumeroCobro()).append("|");              
            }
            if (exp.getMoneda()){
                if (x.getMonedaDto() != null){
                    strCuerpo.append(x.getMonedaDto().getDescripcion()).append("|");
                }
                else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getDocumentoVenta()){
                if (x.getDocumentoVentaDto() != null){
                    strCuerpo.append(x.getDocumentoVentaDto().getId()).append("|");
                }
                else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getUsuarioCancelacion()){
                if (x.getUsuarioCancelacionDto() != null){
                    strCuerpo.append(x.getUsuarioCancelacionDto().getDescripcion()).append("|");
                }
                else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getFechaCancelacion()){
                if (x.getFechaCancelacion() != null){
                    strCuerpo.append(x.getFechaCancelacion()).append("|");
                }
                else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getOrden()){
                strCuerpo.append(x.getOrden()).append("|");  
            }
            if (exp.getEstado()){
                if (x.getEstado() != null){
                    strCuerpo.append(x.getEstadoTexto()).append("|");
                }
                else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getUsuarioCreacion()){
                if (x.getUsuarioCreacionDto() != null){
                    strCuerpo.append(x.getUsuarioCreacionDto().getDescripcion()).append("|");
                }
                else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getFechaCreacion()){
                if (x.getFechaCreacion() != null){
                    strCuerpo.append(x.getFechaCreacion()).append("|");
                }
                else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getTerminalCreacion()){
                if (x.getTerminalCreacion() != null){
                    strCuerpo.append(x.getTerminalCreacion()).append("|");
                }
                else {
                    strCuerpo.append("-").append("|");
                }
            }
            if (exp.getComentario()){
                if (x.getComentario() != null){
                    strCuerpo.append(x.getComentario()).append("|");
                }
                else {
                    strCuerpo.append("-").append("|");
                }
            }
            lstFilas.add(strCuerpo.toString());
        }
        return lstFilas;
    }
    
    private StringBuilder obtenerCabeceraExcel(ExportarExcelCaja.PlanCobro exp) {
        StringBuilder strCabecera = new StringBuilder();
        if (exp.getId()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("general.label.id")).append("|");
        }
        if (exp.getFechaVencimiento()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("plan.cobro.fecha.vencimiento")).append("|");
        }
        if (exp.getFormaPago()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("plan.cobro.forma.pago")).append("|");
        }
        if (exp.getLiquidar()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("plan.cobro.a.liquidar")).append("|");
        }
        if (exp.getCobrado()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("plan.cobro.cobrado")).append("|");
        }
        if (exp.getPendiente()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("plan.cobro.pendiente")).append("|");
        }
        if (exp.getUltimoCobro()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("plan.cobro.ultimo.cobro")).append("|");
        }
        if (exp.getNumeroCobro()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("plan.cobro.numero.cobros")).append("|");
        }
        if (exp.getMoneda()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("plan.cobro.moneda")).append("|");
        }
        if (exp.getDocumentoVenta()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("plan.cobro.documento.venta")).append("|");
        }
        if (exp.getUsuarioCancelacion()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("plan.cobro.usuario.cancelacion")).append("|");
        }
        if (exp.getFechaCancelacion()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("plan.cobro.fecha.cancelacion")).append("|");
        }
        if (exp.getOrden()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("plan.cobro.orden")).append("|");
        }
        if (exp.getEstado()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("general.label.estado")).append("|");
        }
        if (exp.getUsuarioCreacion()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("plan.cobro.usuario.creacion")).append("|");
        }
        if (exp.getFechaCreacion()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("plan.cobro.fecha.creacion")).append("|");
        }
        if (exp.getTerminalCreacion()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("plan.cobro.terminal.creacion")).append("|");
        }
        if (exp.getComentario()) {
            strCabecera.append(UtilCore.Internacionalizacion.getMensajeInternacional("plan.cobro.comentario")).append("|");
        }
        
        return strCabecera;
    }
    
    public ExportarExcelCaja.PlanCobro onChangeChekExcel(Boolean flag) {
        return new ExportarExcelCaja.PlanCobro(flag);
    }

    public void nuevoMuchos(List<PlanCobroDto> lista) throws DAOException {
        springHibernateDao.guardarColeccion(lista);
    }

    public void eliminarMuchos(List<PlanCobroDto> lista) throws DAOException {
        springHibernateDao.borrarColeccion(lista);
    }

    public static Logger getLogger() {
        return logger;
    }

    public static void setLogger(Logger logger) {
        PlanCobroManager.logger = logger;
    }

    public Long getIdEntidad() {
        return idEntidad;
    }

    public void setIdEntidad(Long idEntidad) {
        this.idEntidad = idEntidad;
    }

    public DAOGenerico<PlanCobroDto> getSpringHibernateDao() {
        return springHibernateDao;
    }

    public void setSpringHibernateDao(DAOGenerico<PlanCobroDto> springHibernateDao) {
        this.springHibernateDao = springHibernateDao;
    }

    public RecursosManager getRecursosManager() {
        return recursosManager;
    }

    public void setRecursosManager(RecursosManager recursosManager) {
        this.recursosManager = recursosManager;
    }    

    public String getUrl() {
        return url;
    }

    public String getUrlLista() {
        return urlLista;
    }
}
